/**
 * 
 */
package com.gragra.dependencyParsing;
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import com.gragra.parseOptions.CommandLineException;
import com.gragra.parseOptions.ListOfIntegerOption;
import com.gragra.parseOptions.Parser;
/**
 * @author Christoph Teichmann
 * 23.09.2013
 */
public abstract class RunOneInThreeOutNTimes
{
	/**
	 * 
	 */
	private int number = 5;
	/**
	 * 
	 */
	private final static String numberOpt = "r";
	/**
	 * 
	 * @param args
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public void runNTimes(String[] args) throws IOException, InterruptedException
	{
		OneInThreeOut runner = makeRunner();
		Parser pa = new Parser();
		runner.addParameters(pa);
		pa.setMaxArgs(2);
		pa.setMinArgs(2);
		pa.setArgumentDescription(0, "name of the input file used");
		pa.setArgumentDescription(1, "prefix output file used");
		pa.addOption(numberOpt, new ListOfIntegerOption("number of times the sampling process will be run, default is 5"));
		pa.setIgnoreUnknown(false);
		try
		{
			pa.parse(args);
		}
		catch(CommandLineException e)
		{
			System.out.println("problem parsing options");
			System.out.println(pa.writeOutHelp());
			System.exit(-1);
		}
		ListOfIntegerOption loi = (ListOfIntegerOption) pa.getInformation(numberOpt);
		if(loi.hasBeenSet())
		{this.number = loi.getSettings()[0];}
		DoubleArrayList[][] lists = new DoubleArrayList[number][];
		for(int i=0;i<number;++i)
		{
			BufferedReader br = new BufferedReader(pa.getFileReaderFromArgument(0));
			BufferedWriter bw1 = new BufferedWriter(new FileWriter(pa.getArgument(1)+"_samp"+"_"+Integer.toString(i)+".txt"));
			BufferedWriter bw2 = new BufferedWriter(new FileWriter(pa.getArgument(1)+"_best"+"_"+Integer.toString(i)+".txt"));
			lists[i] = runner.makeParses(pa, br, bw1, bw2);
			br.close();
			bw1.close();
			bw2.close();
		}
		BufferedWriter bw3 = new BufferedWriter(new FileWriter(pa.getArgument(1)+"_conv.txt"));
		bw3.write("Iteration, Function Evaluations, Function Evaluations Normalized Variance, Auxiliary Function Evaluations, Auxiliary Function Evaluations Normalized Variance, Best Seen Mean, Best Seen Variance");
		for(int i=0;i<lists[0][0].size();++i)
		{
			double mean = 0.0;
			bw3.newLine();
			bw3.write(Integer.toString(i+1));
			meanAndVariance(lists, bw3, i, mean, 1);
			meanAndVariance(lists, bw3, i, mean, 2);
			meanAndVariance(lists, bw3, i, mean, 0);
		}
		bw3.close();
	}
	/**
	 * @param lists
	 * @param bw3
	 * @param i
	 * @param mean
	 * @param num
	 * @throws IOException
	 */
	protected void meanAndVariance(DoubleArrayList[][] lists,
			BufferedWriter bw3, int i, double mean, int num) throws IOException
	{
		for(int k=0;k<number;++k)
		{mean += lists[k][num].getDouble(i);}
		mean /= (double) number;
		double variance = 0.0;
		for(int k=0;k<number;++k)
		{variance += Math.pow((lists[k][num].getDouble(i)-mean)/mean, 2.0);}
		variance /= number;
		bw3.write(",");
		bw3.write(Double.toString(mean));
		bw3.write(",");
		bw3.write(Double.toString(variance));
	}
	/**)
	 * 
	 * @return
	 */
	protected abstract OneInThreeOut makeRunner();
}